package system_service

import (
	"errors"
	"fmt"
	"github.com/APP/global"
	"github.com/APP/internal/models"
	"github.com/APP/internal/utils"
	"gorm.io/gorm"
	"time"
)

type RoleService struct {
	mpttManager *utils.MPTTManager
}

func NewRoleService() *RoleService {
	return &RoleService{
		mpttManager: utils.NewMPTTManager(),
	}
}

// CreateRole 创建角色
func (s *RoleService) CreateRole(role *models.SysRole) (*models.SysRole, error) {
	// 检查角色编码是否已存在
	var existingRole models.SysRole
	if err := global.APP_DB.Where("role_code = ? AND deleted_at IS NULL", role.RoleCode).First(&existingRole).Error; err == nil {
		return nil, errors.New("角色编码已存在")
	} else if !errors.Is(err, gorm.ErrRecordNotFound) {
		return nil, fmt.Errorf("检查角色编码失败: %v", err)
	}

	// 如果有父级角色，检查父级角色是否存在
	if role.ParentID != nil {
		var parentRole models.SysRole
		if err := global.APP_DB.Where("id = ? AND deleted_at IS NULL", *role.ParentID).First(&parentRole).Error; err != nil {
			if errors.Is(err, gorm.ErrRecordNotFound) {
				return nil, errors.New("父级角色不存在")
			}
			return nil, fmt.Errorf("检查父级角色失败: %v", err)
		}
	}

	// 设置创建时间
	role.CreatedAt = time.Now()
	role.UpdatedAt = time.Now()

	// 使用MPTT管理器插入节点
	if err := s.mpttManager.InsertNode(role, role.ParentID); err != nil {
		return nil, fmt.Errorf("创建角色失败: %v", err)
	}

	return role, nil
}

// UpdateRole 更新角色
func (s *RoleService) UpdateRole(role *models.SysRole) (*models.SysRole, error) {
	// 检查角色是否存在
	var existingRole models.SysRole
	if err := global.APP_DB.Where("id = ? AND deleted_at IS NULL", role.ID).First(&existingRole).Error; err != nil {
		if errors.Is(err, gorm.ErrRecordNotFound) {
			return nil, errors.New("角色不存在")
		}
		return nil, fmt.Errorf("查询角色失败: %v", err)
	}

	// 检查角色编码是否与其他角色冲突
	var conflictRole models.SysRole
	if err := global.APP_DB.Where("role_code = ? AND id != ? AND deleted_at IS NULL", role.RoleCode, role.ID).First(&conflictRole).Error; err == nil {
		return nil, errors.New("角色编码已存在")
	} else if !errors.Is(err, gorm.ErrRecordNotFound) {
		return nil, fmt.Errorf("检查角色编码失败: %v", err)
	}

	// 如果有父级角色，检查父级角色是否存在
	if role.ParentID != nil {
		var parentRole models.SysRole
		if err := global.APP_DB.Where("id = ? AND deleted_at IS NULL", *role.ParentID).First(&parentRole).Error; err != nil {
			if errors.Is(err, gorm.ErrRecordNotFound) {
				return nil, errors.New("父级角色不存在")
			}
			return nil, fmt.Errorf("检查父级角色失败: %v", err)
		}

		// 检查是否形成循环引用
		if *role.ParentID == role.ID {
			return nil, errors.New("不能将自己设置为父级角色")
		}

		// 检查是否将父级设置为自己的子级（通过MPTT检查）
		var children []models.SysRole
		if err := s.mpttManager.GetChildren(role.ID, role.TableName(), &children); err == nil {
			for _, child := range children {
				if child.ID == *role.ParentID {
					return nil, errors.New("不能将子级角色设置为父级角色")
				}
			}
		}
	}

	// 检查是否需要移动节点
	if (existingRole.ParentID == nil && role.ParentID != nil) ||
		(existingRole.ParentID != nil && role.ParentID == nil) ||
		(existingRole.ParentID != nil && role.ParentID != nil && *existingRole.ParentID != *role.ParentID) {
		// 需要移动节点
		if err := s.mpttManager.MoveNode(role.ID, role.ParentID, role.TableName()); err != nil {
			return nil, fmt.Errorf("移动角色节点失败: %v", err)
		}
	}

	// 更新字段
	updates := map[string]interface{}{
		"parent_id":   role.ParentID,
		"role_name":   role.RoleName,
		"role_code":   role.RoleCode,
		"description": role.Description,
		"status":      role.Status,
		"sort":        role.Sort,
		"updated_at":  time.Now(),
	}

	if err := global.APP_DB.Model(&existingRole).Updates(updates).Error; err != nil {
		return nil, fmt.Errorf("更新角色失败: %v", err)
	}

	// 重新查询更新后的数据
	if err := global.APP_DB.Where("id = ?", role.ID).First(&existingRole).Error; err != nil {
		return nil, fmt.Errorf("查询更新后的角色失败: %v", err)
	}

	return &existingRole, nil
}

// DeleteRole 删除角色
func (s *RoleService) DeleteRole(id int64) error {
	// 检查角色是否存在
	var role models.SysRole
	if err := global.APP_DB.Where("id = ? AND deleted_at IS NULL", id).First(&role).Error; err != nil {
		if errors.Is(err, gorm.ErrRecordNotFound) {
			return errors.New("角色不存在")
		}
		return fmt.Errorf("查询角色失败: %v", err)
	}

	// 检查是否有子角色
	var children []models.SysRole
	if err := s.mpttManager.GetChildren(id, role.TableName(), &children); err != nil {
		return fmt.Errorf("检查子角色失败: %v", err)
	}

	if len(children) > 0 {
		return errors.New("该角色下还有子角色，无法删除")
	}

	// 检查是否有用户关联此角色
	var count int64
	if err := global.APP_DB.Table("sys_user_roles").Where("role_id = ?", id).Count(&count).Error; err != nil {
		return fmt.Errorf("检查用户关联失败: %v", err)
	}

	if count > 0 {
		return errors.New("该角色已分配给用户，无法删除")
	}

	// 使用MPTT管理器删除节点
	if err := s.mpttManager.DeleteNode(&role); err != nil {
		return fmt.Errorf("删除角色失败: %v", err)
	}

	return nil
}

// GetRole 获取角色详情
func (s *RoleService) GetRole(id int64) (*models.SysRole, error) {
	var role models.SysRole
	if err := global.APP_DB.Where("id = ? AND deleted_at IS NULL", id).First(&role).Error; err != nil {
		if errors.Is(err, gorm.ErrRecordNotFound) {
			return nil, errors.New("角色不存在")
		}
		return nil, fmt.Errorf("查询角色失败: %v", err)
	}

	return &role, nil
}

// GetRoleList 获取角色列表
func (s *RoleService) GetRoleList(page, pageSize int, roleName, roleCode string, status *int) ([]*models.SysRole, int64, error) {
	var roles []*models.SysRole
	var total int64

	// 构建查询条件
	query := global.APP_DB.Model(&models.SysRole{}).Where("deleted_at IS NULL")

	if roleName != "" {
		query = query.Where("role_name LIKE ?", "%"+roleName+"%")
	}
	if roleCode != "" {
		query = query.Where("role_code LIKE ?", "%"+roleCode+"%")
	}
	if status != nil {
		query = query.Where("status = ?", *status)
	}

	// 获取总数
	if err := query.Count(&total).Error; err != nil {
		return nil, 0, fmt.Errorf("查询角色总数失败: %v", err)
	}

	// 分页查询
	offset := (page - 1) * pageSize
	if err := query.Order("`left` ASC").Offset(offset).Limit(pageSize).Find(&roles).Error; err != nil {
		return nil, 0, fmt.Errorf("查询角色列表失败: %v", err)
	}

	return roles, total, nil
}

// GetRoleTree 获取角色树形结构
func (s *RoleService) GetRoleTree() ([]*models.SysRole, error) {
	var roles []*models.SysRole

	// 查询所有启用的角色，按左值排序
	if err := global.APP_DB.Where("status = ? AND deleted_at IS NULL", 1).Order("`left` ASC").Find(&roles).Error; err != nil {
		return nil, fmt.Errorf("查询角色树失败: %v", err)
	}

	return roles, nil
}

// GetRoleChildren 获取角色的所有子角色
func (s *RoleService) GetRoleChildren(id int64) ([]*models.SysRole, error) {
	var children []*models.SysRole
	if err := s.mpttManager.GetChildren(id, "sys_roles", &children); err != nil {
		return nil, fmt.Errorf("查询子角色失败: %v", err)
	}

	return children, nil
}

// GetRoleAncestors 获取角色的所有祖先角色
func (s *RoleService) GetRoleAncestors(id int64) ([]*models.SysRole, error) {
	var ancestors []*models.SysRole
	if err := s.mpttManager.GetAncestors(id, "sys_roles", &ancestors); err != nil {
		return nil, fmt.Errorf("查询祖先角色失败: %v", err)
	}

	return ancestors, nil
}

// AssignPermissions 为角色分配权限
func (s *RoleService) AssignPermissions(roleID int64, permissionIDs []int64) error {
	// 检查角色是否存在
	var role models.SysRole
	if err := global.APP_DB.Where("id = ? AND deleted_at IS NULL", roleID).First(&role).Error; err != nil {
		if errors.Is(err, gorm.ErrRecordNotFound) {
			return errors.New("角色不存在")
		}
		return fmt.Errorf("查询角色失败: %v", err)
	}

	return global.APP_DB.Transaction(func(tx *gorm.DB) error {
		// 删除原有权限关联
		if err := tx.Where("role_id = ?", roleID).Delete(&models.SysRolePermission{}).Error; err != nil {
			return fmt.Errorf("删除原有权限关联失败: %v", err)
		}

		// 添加新的权限关联
		for _, permissionID := range permissionIDs {
			rolePermission := &models.SysRolePermission{
				RoleID:       roleID,
				PermissionID: permissionID,
			}
			if err := tx.Create(rolePermission).Error; err != nil {
				return fmt.Errorf("创建权限关联失败: %v", err)
			}
		}

		return nil
	})
}

// GetRolePermissions 获取角色的权限列表
func (s *RoleService) GetRolePermissions(roleID int64) ([]int64, error) {
	var permissions []models.SysRolePermission
	if err := global.APP_DB.Where("role_id = ?", roleID).Find(&permissions).Error; err != nil {
		return nil, fmt.Errorf("查询角色权限失败: %v", err)
	}

	var permissionIDs []int64
	for _, permission := range permissions {
		permissionIDs = append(permissionIDs, permission.PermissionID)
	}

	return permissionIDs, nil
}

// RebuildRoleTree 重建角色树
func (s *RoleService) RebuildRoleTree() error {
	if err := s.mpttManager.RebuildTree("sys_roles"); err != nil {
		return fmt.Errorf("重建角色树失败: %v", err)
	}
	return nil
}

// ValidateRoleTree 验证角色树的完整性
func (s *RoleService) ValidateRoleTree() error {
	if err := s.mpttManager.ValidateTree("sys_roles"); err != nil {
		return fmt.Errorf("角色树验证失败: %v", err)
	}
	return nil
}
